#define _CRT_SECURE_NO_WARNINGS 1

#include <cstring>
#include <iostream>
#include <algorithm>
#include <list>
#include "string.h"

using namespace std;

void test1()
{
	string s1("hello world");  //带参构造

	string s2(s1);   // 拷贝构造

	//s1[i] 的实际写法 s1.operator(i); 
	// s1.operator(i) 和 iterator都有 const的情况 const _interator
	//注意：const _interator是interator指向的数据不能修改 如果是 const interator的话那么就是interator本身不能修改

	string::iterator it1 = s1.begin();

	while (it1 != s1.end())
	{
		cout << *it1 << " ";
		it1++;
	}

	list<int> lt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);
	lt1.push_back(4);

	list<int>::iterator it = lt1.begin();
	while (it != lt1.end())
	{
		cout << *it << " ";
		it++;
	}

	// 总计四种迭代器
	//反向迭代器
	string s3("hello");
	sort(s3.begin(), s3.end());    // 都是左闭右开区间
	string::reverse_iterator it2 = s3.rbegin();

	while (it2 != s3.rend())
	{
		cout << *it2 << " ";
		++it2;
	}

	cout << endl;

	//底层就是迭代器 
	for (auto& e : lt1)
	{
		cout << e << " ";
	}

	string s4("helloworld");
	s3.push_back('x');

	cout << s4 << endl;

	// 追加
	s4.append("yyy!!");

	//不如
	s4 += "12";
	s4.pop_back();
	cout << s4 << endl;


	//insert方法 慎用效率不高 类似顺序表
	string ss("helloworld");
	ss.insert(0, "xxxx");   // 时间复杂度 O(n)
	cout << ss << endl;

	//头插
	ss.insert(0, "a");
	ss.insert(0, 1, 'a');
	ss.insert(ss.begin(), 'a');

	cout << ss << endl;

	//插入s1 迭代器写法
	ss.insert(ss.begin(), s1.begin(), s1.end());
	cout << ss << endl;


	//删除erase 效率也很低和insert差不多
	ss.erase(0, 5);  //啥都不传就删完了
	cout << ss << endl;

	ss.replace(5, 1, "%20");
	cout << ss << endl;

	// reserve 不一定会缩容 但会扩容 意义是直接reserve就不用一直倍增扩容了 提前开空间
	cout << ss.capacity() << endl;
	ss.reserve(100);
	cout << ss.capacity() << endl;



	// 注意不会改变size 所以不能越界访问
	// 这个时候resize就出现了 就可以用下标进行访问了



	string str;
	str.resize(5, '0');

	str[3] = '1';
	cout << str[2] << endl;

	cout << str.size() << endl;



	s1.clear();
	s1 = "hello world";
	s1.resize(15, 'x');    //如果有剩余位置 就在剩余位置填充 不会覆盖原有位置

	cout << s1 << endl;
	cout << s1.size() << " " << s1.capacity() << endl;


	//注意空间不能分段释放 所以shink_to_fit实际上是重新分配了一块空间，再拷贝 以时间换空间


	string file("stl.cpp");

	//c_str返回string的指针 相同与数组首元素地址
	FILE* fout = fopen(file.c_str(), "r");   //只能传const char* c和c++的不同之处 这个时候c_str这个时候就派上用场了
	char ch = fgetc(fout);
	while (ch != EOF)
	{
		cout << ch;
		ch = fgetc(fout);
	}

	cout << '\n';

	size_t pos = file.rfind(".");  //从前往后倒着找. 找到返回对应的下标
	//string suffix = file.substr(pos, file.size() - pos);
	string suffix = file.substr(pos);  //有多少取多少

	cout << suffix << endl;




	string s = "12345";
	//int num1 = stoi(s);
}

int main()
{
	//test1();
	
	bit::string s1("hello world");

	cout << s1.c_str() << " ";

	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}


	for (auto& e : s1)
	{
		cout << e << " ";
	}
	cout << endl;

	bit::string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		++it;
	}

	bit::string s2("hello world");
	cout << s2 << endl;

	cin >> s2;
	cout << s2 << endl; 


	return 0;
}



